logging Middleware
Routes a model invocation's tool-call boundary + error events through an injected Logger — the port-side, provider-agnostic home for observability.
Logging belongs in middleware, not in the provider (which stays focused on engine ↔ SDK translation) nor the agent loop. This is the canonical consumer of the Logger primitive: a host injects its platform Logger (Logcat / Crashlytics / os_log adapter) and wraps its model with wrapLanguageModel(model, listOf(loggingMiddleware(logger))).
Routing:
StreamEvent.ToolError → Logger.warn, passing the
@Transienttyped StreamEvent.ToolError.error as the throwable when present.tool-open / tool-call / tool-result → Logger.debug so production hosts can gate verbosity.
Routine
TextDelta/ReasoningDeltatokens are never logged — that would flood the sink.
wrapGenerate logs a one-line completion summary; the streaming path (the chat surface) carries the per-event detail.